#include "server_simulator.h"
#include <dlfcn.h>
#include <cstring>
#include <iostream>

// 磁盘动态库接口类型定义
typedef void* (*disk_create_t)(const char*, std::size_t);
typedef void  (*disk_destroy_t)(void*);
typedef int   (*disk_power_on_t)(void*);
typedef int   (*disk_power_off_t)(void*);
typedef std::size_t (*disk_get_size_t)(void*);

struct ServerSimulator::DiskHandle {
    void* disk_ptr;
};

class DiskLibLoader {
public:
    void* handle;
    disk_create_t disk_create;
    disk_destroy_t disk_destroy;
    disk_power_on_t disk_power_on;
    disk_power_off_t disk_power_off;
    disk_get_size_t disk_get_size;
    DiskLibLoader() : handle(nullptr) {
        handle = dlopen("../../disk/build/libdisk_simulator.so", RTLD_LAZY);
        if (!handle) throw std::runtime_error("无法加载disk动态库");
        disk_create = (disk_create_t)dlsym(handle, "disk_create");
        disk_destroy = (disk_destroy_t)dlsym(handle, "disk_destroy");
        disk_power_on = (disk_power_on_t)dlsym(handle, "disk_power_on");
        disk_power_off = (disk_power_off_t)dlsym(handle, "disk_power_off");
        disk_get_size = (disk_get_size_t)dlsym(handle, "disk_get_size");
    }
    ~DiskLibLoader() { if (handle) dlclose(handle); }
};

// 新增：通过SN读写磁盘的实现
static ServerSimulator* g_server_instance = nullptr;  // 用于演示，实际应使用map或其他数据结构管理多个实例

ServerSimulator::ServerSimulator(const std::string& manufacturer, const std::string& sn, int disk_count, const std::vector<std::size_t>& disk_sizes)
    : manufacturer_(manufacturer), sn_(sn), powered_on_(false), fault_code_(0), disk_lib_handle_(nullptr) {
    g_server_instance = this;  // 保存实例指针
    DiskLibLoader* loader = new DiskLibLoader();
    disk_lib_handle_ = loader;
    for (int i = 0; i < disk_count; ++i) {
        char disk_file[64];
        snprintf(disk_file, sizeof(disk_file), "disk_%d.img", i);
        void* disk = loader->disk_create(disk_file, disk_sizes[i]);
        disks_.push_back(new DiskHandle{disk});
    }
}

ServerSimulator::~ServerSimulator() {
    if (g_server_instance == this) {
        g_server_instance = nullptr;
    }
    DiskLibLoader* loader = (DiskLibLoader*)disk_lib_handle_;
    for (auto d : disks_) {
        loader->disk_destroy(d->disk_ptr);
        delete d;
    }
    delete loader;
}

int ServerSimulator::power_on() {
    powered_on_ = true;
    DiskLibLoader* loader = (DiskLibLoader*)disk_lib_handle_;
    for (auto d : disks_) loader->disk_power_on(d->disk_ptr);
    return 0;
}
int ServerSimulator::power_off() {
    powered_on_ = false;
    DiskLibLoader* loader = (DiskLibLoader*)disk_lib_handle_;
    for (auto d : disks_) loader->disk_power_off(d->disk_ptr);
    return 0;
}
bool ServerSimulator::is_powered_on() const { return powered_on_; }
int ServerSimulator::set_fault(int fault_code) { fault_code_ = fault_code; return 0; }
int ServerSimulator::clear_fault() { fault_code_ = 0; return 0; }
int ServerSimulator::get_fault_code() const { return fault_code_; }
int ServerSimulator::get_disk_count() const { return disks_.size(); }
std::size_t ServerSimulator::get_disk_size(int disk_index) const {
    if (disk_index < 0 || disk_index >= (int)disks_.size()) return 0;
    DiskLibLoader* loader = (DiskLibLoader*)disk_lib_handle_;
    return loader->disk_get_size(disks_[disk_index]->disk_ptr);
}
std::string ServerSimulator::get_manufacturer() const { return manufacturer_; }
std::string ServerSimulator::get_sn() const { return sn_; }

// C接口实现
extern "C" {
void* server_create(const char* manufacturer, const char* sn, int disk_count, const std::size_t* disk_sizes) {
    std::vector<std::size_t> sizes(disk_sizes, disk_sizes + disk_count);
    return new ServerSimulator(manufacturer, sn, disk_count, sizes);
}
void server_destroy(void* server) { delete (ServerSimulator*)server; }
int server_power_on(void* server) { return ((ServerSimulator*)server)->power_on(); }
int server_power_off(void* server) { return ((ServerSimulator*)server)->power_off(); }
int server_is_powered_on(void* server) { return ((ServerSimulator*)server)->is_powered_on(); }
int server_set_fault(void* server, int fault_code) { return ((ServerSimulator*)server)->set_fault(fault_code); }
int server_clear_fault(void* server) { return ((ServerSimulator*)server)->clear_fault(); }
int server_get_fault_code(void* server) { return ((ServerSimulator*)server)->get_fault_code(); }
int server_get_disk_count(void* server) { return ((ServerSimulator*)server)->get_disk_count(); }
std::size_t server_get_disk_size(void* server, int disk_index) { return ((ServerSimulator*)server)->get_disk_size(disk_index); }
int server_get_manufacturer(void* server, char* manufacturer, std::size_t len) {
    std::string m = ((ServerSimulator*)server)->get_manufacturer();
    strncpy(manufacturer, m.c_str(), len);
    return 0;
}
int server_get_sn(void* server, char* sn, std::size_t len) {
    std::string s = ((ServerSimulator*)server)->get_sn();
    strncpy(sn, s.c_str(), len);
    return 0;
}
int server_get_info(void* server, struct ServerInfo* info) {
    if (!server || !info) return -1;
    ServerSimulator* s = (ServerSimulator*)server;
    info->powered_on = s->is_powered_on();
    info->fault_code = s->get_fault_code();
    info->disk_count = s->get_disk_count();
    for (int i = 0; i < info->disk_count && i < 32; ++i) {
        info->disk_sizes[i] = s->get_disk_size(i);
    }
    std::string m = s->get_manufacturer();
    std::string sn = s->get_sn();
    strncpy(info->manufacturer, m.c_str(), sizeof(info->manufacturer));
    info->manufacturer[sizeof(info->manufacturer)-1] = '\0';
    strncpy(info->sn, sn.c_str(), sizeof(info->sn));
    info->sn[sizeof(info->sn)-1] = '\0';
    return 0;
}
int server_get_disk_sn(void* server, int disk_index, char* sn, std::size_t sn_len) {
    if (!server || !sn || disk_index < 0) return -1;
    ServerSimulator* s = (ServerSimulator*)server;
    if (disk_index >= s->get_disk_count()) return -2;
    
    // 为简单演示，这里用disk_index生成一个唯一的磁盘SN
    snprintf(sn, sn_len, "DISK_SN_%d", disk_index);
    return 0;
}
int server_read_disk_by_sn(const char* server_sn, const char* disk_sn, std::size_t offset, void* buf, std::size_t len) {
    if (!server_sn || !disk_sn || !buf) return -1;
    if (!g_server_instance) return -2;
    
    // 检查服务器SN是否匹配
    std::string curr_sn = g_server_instance->get_sn();
    if (curr_sn != server_sn) return -3;
    
    // 从disk_sn中提取disk_index（简单演示）
    int disk_index = -1;
    sscanf(disk_sn, "DISK_SN_%d", &disk_index);
    if (disk_index < 0 || disk_index >= g_server_instance->get_disk_count()) return -4;
    
    // 调用对应磁盘的读操作
    DiskLibLoader* loader = (DiskLibLoader*)g_server_instance->disk_lib_handle_;
    ServerSimulator::DiskHandle* disk = g_server_instance->disks_[disk_index];
    if (!disk) return -5;
    
    int (*disk_read)(void*, std::size_t, void*, std::size_t) = 
        (int(*)(void*, std::size_t, void*, std::size_t))dlsym(loader->handle, "disk_read");
    if (!disk_read) return -6;
    
    return disk_read(disk->disk_ptr, offset, buf, len);
}
int server_write_disk_by_sn(const char* server_sn, const char* disk_sn, std::size_t offset, const void* buf, std::size_t len) {
    if (!server_sn || !disk_sn || !buf) return -1;
    if (!g_server_instance) return -2;
    
    // 检查服务器SN是否匹配
    std::string curr_sn = g_server_instance->get_sn();
    if (curr_sn != server_sn) return -3;
    
    // 从disk_sn中提取disk_index（简单演示）
    int disk_index = -1;
    sscanf(disk_sn, "DISK_SN_%d", &disk_index);
    if (disk_index < 0 || disk_index >= g_server_instance->get_disk_count()) return -4;
    
    // 调用对应磁盘的写操作
    DiskLibLoader* loader = (DiskLibLoader*)g_server_instance->disk_lib_handle_;
    ServerSimulator::DiskHandle* disk = g_server_instance->disks_[disk_index];
    if (!disk) return -5;
    
    int (*disk_write)(void*, std::size_t, const void*, std::size_t) = 
        (int(*)(void*, std::size_t, const void*, std::size_t))dlsym(loader->handle, "disk_write");
    if (!disk_write) return -6;
    
    return disk_write(disk->disk_ptr, offset, buf, len);
}
} 